//----------------------------------------------------------------------------------------------------------------------
/// \file
/// <summary>Controller class for event trace sessions</summary>
// Copyright (c) Microsoft Corporation.  All Rights Reserved.
//----------------------------------------------------------------------------------------------------------------------
#pragma once
#include "EtwProcessor.h"

#include <Windows.h>

namespace Etw { namespace Processor
{
    /// <summary>
    /// Controller class to start and stop trace sessions
    /// </summary>
    class ETWPROCESSOR_API EtwController
    {
    public:
        /// <summary>Method to start an event trace session</summary>
        /// <param name="pszTraceName">Name of the trace session</param>
        /// <param name="maximumFileSize">Maximum file size in megabytes</param>
        /// <returns>S_OK if successfully started the trace</returns>
        static HRESULT StartEtwTrace(const wchar_t* pszTraceName, unsigned long maximumFileSize = c_defaultMaxFileSize);

        /// <summary>Method to start an event trace session</summary>
        /// <param name="pszTraceName">Name of the trace session</param>
        /// <param name="pszFileName">Name of the etl file</param>
        /// <param name="maximumFileSize">Maximum file size in megabytes</param>
        /// <returns>S_OK if successfully started the trace</returns>
        static HRESULT StartEtwTrace(const wchar_t* pszTraceName, const wchar_t* pszFileName, unsigned long maximumFileSize = c_defaultMaxFileSize);

        /// <summary>Method to stop an event trace session</summary>
        /// <param name="pszTraceName">Name of the trace session</param>
        /// <returns>S_OK if successfully stopped the trace</returns>
        static HRESULT StopEtwTrace(const wchar_t* pszTraceName);

        /// <summary>Method to add/register an event provider in a trace session</summary>
        /// <param name="pszTraceName">Name of the trace session</param>
        /// <param name="providerGuid">Guid of the event provider</param>
        /// <param name="level">Provider defined value that specifies level of detail included in the event</param>
        /// <param name="matchAnyKeyword">Bit mask of keywords that determine the category of events</param>
        /// <param name="matchAllKeyword">Bit mask of keywords that determine the category of events</param>
        /// <param name="enableProperty">Optional information that Etw can include when writing the events</param>
        /// <returns>S_OK if successfully enabled the provider</returns>
        static HRESULT EnableProvider(const wchar_t* pszTraceName, const GUID &providerGuid, unsigned char level, unsigned __int64 matchAnyKeyword, unsigned __int64 matchAllKeyword, unsigned long enableProperty);

        /// <summary>Method to add/register an event provider in a trace session</summary>
        /// <param name="pszTraceName">Name of the trace session</param>
        /// <param name="providerGuid">Guid of the event provider</param>
        /// <returns>S_OK if successfully enabled the provider</returns>
        static HRESULT EnableProvider(const wchar_t* pszTraceName, const GUID &providerGuid);

        /// <summary>Method to un-register/remove an event provider in a trace session</summary>
        /// <param name="pszTraceName">Name of the trace session</param>
        /// <param name="providerGuid">Guid of the event provider</param>
        /// <returns>S_OK if successfully disabled the provider</returns>
        static HRESULT DisableProvider(const wchar_t* pszTraceName, REFGUID providerGuid);

        /// <summary>Method to flush events of a trace session</summary>
        /// <param name="pszTraceName">Name of the trace session</param>
        /// <returns>S_OK if successfully flushed the events</returns>
        static HRESULT Flush(const wchar_t* pszTraceName);

        #ifdef ETWPROCESSOR_FULL_BUILD
        static HRESULT StartEtwTrace(const __wchar_t* pszTraceName, unsigned long maximumFileSize = c_defaultMaxFileSize)
        {
            return EtwController::StartEtwTrace(reinterpret_cast<const wchar_t*>(pszTraceName), maximumFileSize);
        }

        static HRESULT StartEtwTrace(const __wchar_t* pszTraceName, const __wchar_t* pszFileName, unsigned long maximumFileSize = c_defaultMaxFileSize)
        {
            return EtwController::StartEtwTrace(reinterpret_cast<const wchar_t*>(pszTraceName), reinterpret_cast<const wchar_t*>(pszFileName), maximumFileSize);
        }

        static HRESULT StopEtwTrace(const __wchar_t* pszTraceName)
        {
            return EtwController::StopEtwTrace(reinterpret_cast<const wchar_t*>(pszTraceName));
        }

        static HRESULT EnableProvider(const __wchar_t* pszTraceName, const GUID &providerGuid, unsigned char level, unsigned __int64 matchAnyKeyword, unsigned __int64 matchAllKeyword, unsigned long enableProperty)
        {
            return EtwController::EnableProvider(reinterpret_cast<const wchar_t*>(pszTraceName), providerGuid, level, matchAnyKeyword, matchAllKeyword, enableProperty);
        }

        static HRESULT EnableProvider(const __wchar_t* pszTraceName, const GUID &providerGuid)
        {
            return EtwController::EnableProvider(reinterpret_cast<const wchar_t*>(pszTraceName), providerGuid);
        }

        static HRESULT DisableProvider(const __wchar_t* pszTraceName, REFGUID providerGuid)
        {
            return EtwController::DisableProvider(reinterpret_cast<const wchar_t*>(pszTraceName), providerGuid);
        }

        static HRESULT Flush(const __wchar_t* pszTraceName)
        {
            return EtwController::Flush(reinterpret_cast<const wchar_t*>(pszTraceName));
        }
        #endif

    private:
        EtwController();//not implemented
        ~EtwController();//not implemented
        EtwController(const EtwController&);//not implemented
        EtwController& operator=(const EtwController&);//not implemented

        static const unsigned long c_defaultMaxFileSize = 200;
    };
} /* namespace Processor */ } /* namespace Etw */
